package com.bckj.fastboot.core.extra.license;

import com.bckj.fastboot.core.extra.license.configuration.LicenseVerifyProperties;
import de.schlichtherle.license.*;

import java.io.File;
import java.util.List;
import java.util.prefs.Preferences;

/**
 * 自定义LicenseManager，增加IP地址、MAC地址等硬件信息校验
 */
public class CustomLicenseManager extends LicenseManager {
    private final LicenseVerifyProperties properties;
    
    public CustomLicenseManager(LicenseVerifyProperties properties) {
        super(initLicenseParam(properties));
        this.properties = properties;
    }

    public LicenseContent install() throws Exception {
        return install(new File(properties.getLicensePath()));
    }
    
    /**
     * 复写validate方法，增加IP地址、MAC地址等其他信息校验
     */
    @Override
    protected synchronized void validate(final LicenseContent content) throws LicenseContentException {
        // 1. 首先调用父类的validate方法（校验有效期等基础信息）
        super.validate(content);
        
        // 2. 然后校验自定义的License参数
        // License中可被允许的参数信息
        LicenseCheckModel expectedCheckModel = (LicenseCheckModel) content.getExtra();
        
        // 当前服务器真实的参数信息
        LicenseCheckModel serverCheckModel = getServerInfos();
        
        if (expectedCheckModel != null && serverCheckModel != null) {
            // 校验IP地址
            if (!checkIpAddress(expectedCheckModel.getIpAddress(), serverCheckModel.getIpAddress())) {
                throw new LicenseContentException("当前服务器的IP地址没在授权范围内");
            }
            
            // 校验MAC地址
            if (!checkMacAddress(expectedCheckModel.getMacAddress(), serverCheckModel.getMacAddress())) {
                throw new LicenseContentException("当前服务器的MAC地址没在授权范围内");
            }
            
            // 校验CPU序列号
            if (!checkSerial(expectedCheckModel.getCpuSerial(), serverCheckModel.getCpuSerial())) {
                throw new LicenseContentException("当前服务器的CPU序列号没在授权范围内");
            }
            
            // 校验主板序列号
            if (!checkSerial(expectedCheckModel.getMainBoardSerial(), serverCheckModel.getMainBoardSerial())) {
                throw new LicenseContentException("当前服务器的主板序列号没在授权范围内");
            }
        } else {
            throw new LicenseContentException("无法获取服务器硬件信息");
        }
    }
    
    /**
     * 获取当前服务器硬件信息
     */
    private LicenseCheckModel getServerInfos() {
        AbstractServerInfos abstractServerInfos = null;
        
        // 根据操作系统类型选择不同的实现
        String osName = System.getProperty("os.name").toLowerCase();
        if (osName.startsWith("windows")) {
            // 需要实现WindowsServerInfos类
             abstractServerInfos = new WindowsServerInfos();
        } else {
            abstractServerInfos = new LinuxServerInfos();
        }
        
        return abstractServerInfos.getServerInfos();
    }
    
    /**
     * 校验IP地址
     */
    private boolean checkIpAddress(List<String> expected, List<String> server) {
        if (expected == null || expected.isEmpty()) {
            return true; // 如果期望列表为空，则不校验
        }
        
        if (server == null || server.isEmpty()) {
            return false;
        }
        
        for (String ip : server) {
            if (expected.contains(ip)) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 校验MAC地址
     */
    private boolean checkMacAddress(List<String> expected, List<String> server) {
        if (expected == null || expected.isEmpty()) {
            return true; // 如果期望列表为空，则不校验
        }
        
        if (server == null || server.isEmpty()) {
            return false;
        }
        
        for (String mac : server) {
            if (expected.contains(mac)) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 校验序列号
     */
    private boolean checkSerial(String expected, String server) {
        if (expected == null || expected.trim().isEmpty()) {
            return true; // 如果期望值为空，则不校验
        }
        
        if (server == null || server.trim().isEmpty()) {
            return false;
        }
        
        return expected.equals(server);
    }

    /**
     * 初始化证书参数
     */
    private static LicenseParam initLicenseParam(LicenseVerifyProperties param) {
        Preferences preferences = Preferences.userNodeForPackage(LicenseVerifyServiceImpl.class);
        CipherParam cipherParam = new DefaultCipherParam(param.getStorePass());

        KeyStoreParam publicStoreParam = new DefaultKeyStoreParam(
                LicenseVerifyServiceImpl.class,
                param.getPublicKeysStorePath(),
                param.getPublicAlias(),
                param.getStorePass(),
                null
        );

        return new DefaultLicenseParam(
                param.getSubject(),
                preferences,
                publicStoreParam,
                cipherParam
        );
    }
}